/*
 *  Environment.cpp
 *  lab3
 *
 *  Created by Fredrik Gustafsson on 11/17/10.
 *  Copyright 2010 Kungliga Tekniska Högskolan. All rights reserved.
 *
 */

#include "Environment.h"

using namespace wok2;

Environment::~Environment() {
	std::vector<Item*>::const_iterator item_it;
	for (item_it = e_items.begin(); item_it!=e_items.end(); item_it++) {
		Item* item = *item_it;
#ifdef DEBUG_DEALLOC
		std::cout << "\t*DBG* Deallocating:" << item->name << std::endl;
#endif
		delete item;
	}
	
	std::vector<Actor*>::iterator it;
	for (it=e_actors.begin(); it!=e_actors.end(); it++) {
		Actor* actor = *it;
#ifdef DEBUG_DEALLOC
		std::cout << "\t*DBG* Deallocating:" << actor->name << std::endl;
#endif
		delete actor;		
	}
}

std::ostream& Environment::write_neighbors(std::ostream& os) const {
	std::map<std::string,Environment*>::const_iterator it;
	for (it = e_neighbors.begin(); it != e_neighbors.end(); it++) {
		os << "@join" << std::endl
		<< name << std::endl
		<< it->first << std::endl
		<< it->second->name << std::endl << std::endl;
	}
	return os;
}

std::ostream& Environment::write_items(std::ostream& os) const {
	std::vector<Item*>::const_iterator item_it;
	for (item_it = e_items.begin(); item_it!=e_items.end(); item_it++) {
		Item* item = *item_it;
		if (item->type().compare("jar")==0) {
			continue;
		}
		if (item != NULL) {
			os << "@" << item->type() << std::endl
			<< item->name << std::endl
			<< item->description << std::endl;
			item->write_nongeneric(os);
			os << std::endl;
		}
	}
	//Save jars (need items to be initialized)
	for (item_it = e_items.begin(); item_it!=e_items.end(); item_it++) {
		Item* item = *item_it;
		if (item->type().compare("jar")!=0) {
			continue;
		}
		if (item != NULL) {
			os << "@" << item->type() << std::endl
			<< item->name << std::endl
			<< item->description << std::endl;
			item->write_nongeneric(os);
			os << std::endl;
		}
	}
	for (item_it = e_items.begin(); item_it != e_items.end(); item_it++) {
		os << "@place" << std::endl
		<< name << std::endl
		<< (*item_it)->name << std::endl << std::endl;
	}
	return os;
}

std::ostream& Environment::write_actors(std::ostream& os) const {
	std::vector<Actor*>::const_iterator it;
	for (it = e_actors.begin(); it != e_actors.end(); it++) {
		Actor* actor = *it;
		os << "@" << actor->type() << std::endl
		<< name << std::endl
		<< actor->name << std::endl;
		actor->write_nongeneric(os);
		os << std::endl;
	}
	return os;
}

Item* Environment::pop_item(std::string item) {
	std::vector<Item*>::iterator it;
	for (it=e_items.begin(); it!=e_items.end(); it++) {
		if (item.compare((*it)->name) == 0) {
			Item* ret = *it;
			e_items.erase(it);
			return ret;
		}
	}
	return NULL;
}

void Environment::push_item(Item* item) {
	e_items.push_back(item);
}

Actor* Environment::pop_actor(std::string actor) {
	std::vector<Actor*>::iterator it;
	for (it=e_actors.begin(); it!=e_actors.end(); it++) {
		if (actor.compare((*it)->name) == 0) {
			Actor* ret = *it;
			e_actors.erase(it);
			return ret;
		}
	}
	return NULL;
}

Actor* Environment::peek_actor(std::string actor) const {
	std::vector<Actor*>::const_iterator it;
	for (it=e_actors.begin(); it!=e_actors.end(); it++) {
		if (actor.compare((*it)->name) == 0) {
			Actor* ret = *it;
			return ret;
		}
	}
	return NULL;
}

void Environment::push_actor(Actor* actor) {
	e_actors.push_back(actor);
}

Environment* Environment::neighbor(std::string str) {
	if (e_neighbors.find(str) == e_neighbors.end()) {
		return NULL;
	}
	return e_neighbors[str];
}

void Environment::add_neighbor(std::string direction, Environment& env) {
	e_neighbors[direction] = &env;
}
void Environment::print_room() {
	std::cout << description << std::endl;
	
	print_actors();
	print_items();
	std::cout << "Exits: " ;
	print_directions();
}

void Environment::print_items() const {
	if ( e_items.empty()){
		return;
	}
	std::cout << "Items here:" << std::endl;
	for (std::vector<Item*>::const_iterator it = e_items.begin(); it != e_items.end(); it++) {
		std::cout << (*it)->name << ": " << (*it)->description << std::endl;
	}
}

void Environment::print_directions() const {
	std::map<std::string,Environment*>::const_iterator it;
	for (it=e_neighbors.begin() ; it != e_neighbors.end(); it++ ){
		if (it!=e_neighbors.begin()){
			std::cout << ", ";
		}
		
		std::cout << (*it).first; //<< " => " << (*it).second->name() << std::endl;
	}
	std::cout << std::endl;
}

void Environment::print_actors() const {
	if ( e_actors.empty()){
		return;
	}
	std::cout<<"Here with you are:\n";
	for (std::vector<Actor*>::const_iterator it = e_actors.begin(); it != e_actors.end(); it++) {
		std::cout << (*it)->name << " of type " << (*it)->type() << std::endl;
	}
}